<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>自定义标签</title>
    <script src="js/three/build/three.js"></script>
    <script src="js/three/examples/js/renderers/CSS2DRenderer.js"></script>
    <script src="js/three/examples/js/controls/OrbitControls.js"></script>
    <link rel="stylesheet" href="common.css">
    <style>
        .txt_label_2D {
            width: 100px;
            height: 60px;
            text-align: center;
            background-color: rgb(199, 47, 110);
            color: #000;
            padding: 2px;
            z-index: 999;
            position: absolute;
        }
    </style>
</head>

<body>

</body>
<script>
    var width = window.innerWidth; //窗口宽度
    var height = window.innerHeight; //窗口高度
    let scene = new THREE.Scene(); // 创建场景
    var plane = createPlaneGeometryBasicMaterial(); //创建地面
    scene.add(plane); //将地面添加到场景中

    // 创建文字标签(threejs内部字体)
    function labelTxt(txt, p) {
        var loader = new THREE.FontLoader();
        loader.load('js/three/examples/fonts/gentilis_regular.typeface.json', function(font) {
            var geometry = new THREE.TextGeometry(txt, {
                font: font,
                size: 50,
                height: 1,
            });
            var fontMaterial = new THREE.MeshLambertMaterial({
                color: 0x808080
            });
            var fontModel = new THREE.Mesh(geometry, fontMaterial);
            fontModel.position.set(p.x, p.y, p.z)
            scene.add(fontModel);
        })
    }
    labelTxt('文字标签abcf', new this.THREE.Vector3(30, 30, 30))

    //精灵文字标签（总是面向摄像头）
    function spriteLabel(txt, p) {
        let canvas = document.createElement("canvas");
        let ctx = canvas.getContext("2d");
        let txtWidth = ctx.measureText(txt).width;
        canvas.width = txtWidth * 10;
        canvas.height = 100;
        ctx.fillStyle = "#ffff00";
        ctx.strokeStyle = "#ffff00";
        ctx.font = "Bold 80px 宋体";
        ctx.fillText(txt, 0, 80);
        let texture = new THREE.Texture(canvas);
        texture.needsUpdate = true;
        let material = new THREE.SpriteMaterial({
            map: texture,
        });
        let text = new THREE.Sprite(material);
        text.scale.set(txtWidth * 10, 100);
        text.position.set(p.x, p.y, p.z);
        scene.add(text)
    }
    spriteLabel('精灵文字标签', new this.THREE.Vector3(30, 100, 30))

    // 自定义2D标签（总是面向摄像头）
    var css2drenderer = new THREE.CSS2DRenderer();
    css2drenderer.setSize(window.innerWidth, window.innerHeight);
    css2drenderer.domElement.style.position = 'absolute';
    css2drenderer.domElement.style.top = 0;
    document.body.appendChild(css2drenderer.domElement);

    function label2D(text, vector) {
        let laberDiv = document.createElement('div'); //创建div容器
        laberDiv.className = 'txt_label_2D';
        laberDiv.setAttribute("id", "label2D")
        laberDiv.innerHTML = text + ' </br> ' + "余量：123";
        let pointLabel = new THREE.CSS2DObject(laberDiv);
        pointLabel.position.set(vector.x, vector.y, vector.z);
        return pointLabel;
    }
    var pointLabel = label2D("hahaha", new this.THREE.Vector3(30, 300, 30));
    scene.add(pointLabel);



    // 创建地面
    function createPlaneGeometryBasicMaterial() {
        let planeGeometry = new THREE.PlaneGeometry(2000, 1000); // 平面网格
        let planeMaterial = new THREE.MeshLambertMaterial({
            color: 0x000000
        });
        let plane = new THREE.Mesh(planeGeometry, planeMaterial);
        plane.rotation.x = -Math.PI / 2
        plane.position.y = 0;
        return plane;
    }

    // 光源
    let AmbientLight = new THREE.AmbientLight(0xffffff);
    scene.add(AmbientLight);

    // 主场景相机
    camera = new this.THREE.PerspectiveCamera(40, width / height, 1, 10000)
    camera.position.set(0, 150, 1000) // 设置相机位置
    camera.lookAt(new this.THREE.Vector3(0, 0, 0)); // 设置相机方向(指向的场景对象)
    var axisHelper = new THREE.AxisHelper(600); // 辅助坐标系
    scene.add(axisHelper);

    // 主场景渲染
    var renderer = new THREE.WebGLRenderer(); //创建渲染器
    document.body.appendChild(renderer.domElement); //body元素中插入canvas对象
    renderer.setSize(width, height); //设置渲染区域尺寸
    renderer.setClearColor(0x00ffff, 0.5) // 设置背景颜色



    // render
    function render() {
        renderer.render(scene, camera);
        requestAnimationFrame(render);
        css2drenderer.render(scene, camera);
    }

    var controls = new THREE.OrbitControls(camera, css2drenderer.domElement) //控制器
    controls.addEventListener('change', (e) => {
        requestAnimationFrame(render)
    }, false)

    render()
</script>

</html>